#pragma once

template <class T>
class Singleton
{
public:
	static T * GetInstance()
	{
		return _pInstance;
	}

	static HRESULT CreateInstance()
	{
		ASSERT(_pInstance == NULL);
		if (_pInstance == NULL)
		{
			_pInstance = new T;
			if (Log)
				Log->Out("CreateInstance(0x%x)\n", _pInstance);
			return _pInstance->OnInitSingleton();
		}
		return S_OK;
	}

	static void DestroyInstance()
	{
		ASSERT(_pInstance != NULL);
		if (_pInstance)
		{
			if (Log)
				Log->Out("DestroyInstance(0x%x)\n", _pInstance);
			_pInstance->OnUninitSingleton();
			delete _pInstance;
		}
		_pInstance = NULL;
	}

	virtual HRESULT OnInitSingleton(void) { return E_NOTIMPL; }
	virtual void OnUninitSingleton(void) { }
protected:
	Singleton() {}
	static T * _pInstance;
private:
	Singleton(const Singleton &) {}
	Singleton & operator=(const Singleton) { return *this; }
};

template <class T>
T* Singleton<T>::_pInstance = NULL;